%load_ext pretty_jupyter
import os,re
import numpy as np
from scipy.interpolate import interp1d
import pandas as pd
from itertools import product
from datetime import datetime

import matplotlib.pyplot as plt
from pretty_jupyter.helpers import matplotlib_fig_to_html, matplotlib_fig_to_markdown
from IPython.display import display, Markdown

import seaborn as sns
from sklearn.linear_model import LinearRegression

import geopandas
import plotly.express as px

import plot_crime as pc
import plot_crime_plotly as pcp

%load_ext autoreload
%autoreload 2
# %matplotlib inline
# %load_ext genai
import plotly.io as pio
# pio.renderers.default = "notebook_connected"
# pio.renderers
# pio.renderers.default = "browser"
include_plotlyjs = 'cdn'
full_html = False
renderer=None#"notebook_connected"
def get_region_df(plot_data,region):
    select_places = community_areas.query('Region == @region')['Name'].values
    return plot_data.query('`Community Area` in @select_places')
base_dir = 'C:\\Users\\BatLab\\Documents\\chicago_crime'
crime_by_year_fname = os.path.join(base_dir,'crime_by_year_dfs.pkl')
crime_by_year_dfs = pd.read_pickle(crime_by_year_fname)

return_raw = False
community_areas, demographics, nibrs_codes, iucr_codes, population, _ = pc.init_crime_data(return_raw)

cca_regions = community_areas.Region.unique()

Crime rates by year

All of the following plots show crime within one of the larger regions of Chicago or within one of the 77 neighborhoods.

Crime type is categorized using FBI standardized type.

Plots are interactive

  • Hover over lines to get more details.
  • Single click on a legend entry to remove that entry from plots
  • Double click on a legend entry to remove all other entries
crime_type = 'FBI_type'
place_type = 'region'
select_crimes = None
select_places = cca_regions

Plotting each crime type per region

In the follow plot, number of crimes in a year are counted within one of 9 regions of Chicago and scaled by the population in that region for that year.

plot_data = pcp.melt_crime_df(
    crime_by_year_dfs,
    crime_type,
    place_type,
    select_crimes=select_crimes,
    population=population,
    select_places=select_places,
    community_areas=community_areas
)

fig = pcp.plot_crime_by_type_and_place(
    plot_data,
    crime_type,
    place_type
)
fig.show(renderer=renderer)

Plotting Crimes within Region by Neighborhood

In this section, use the tabs at the top to select which region to display.

Within those regions, crime rates are plotted separately by the individual neighborhoods making up that region.

crime_type = 'FBI_type'
place_type = 'Community Area'
select_crimes = None
select_places = community_areas.index
select_regions = [r for r in pcp.ordered_regions if r is not None]
for region in select_regions:

    display(Markdown(f"### {region.title()}"))
    plot_data = pcp.melt_crime_df(
        crime_by_year_dfs,
        crime_type,
        place_type,
        select_crimes=select_crimes,
        population=population,
        select_places=select_places,
        community_areas=community_areas
    )
    plot_data = get_region_df(plot_data,region) 
    fig = pcp.plot_crime_by_type_and_place(
            plot_data,
            crime_type,
            place_type
        )
    
    fig.show(renderer=renderer)

Far North Side

Northwest Side

North Side

West Side

Central

Southwest Side

South Side

Far Southwest Side

Far Southeast Side

Plotting Select Crimes by Region

In this section, use the tabs at the top to select which grouping of crime types to display.

Groupings are arbitrarily assigned. "Society" is a grab-all grouping.

Regions are arranged semi-geographically.

Instead of plotting the per-capita rate, in this section the plots show for each given crime type / region what fraction of the maximum crime count across years was obtained in that year.

  • For instance, on the Far North Side, homicides reached their maximum in 2022. So each year will show how many homicides were commited in that year in the Far North Side as a fraction of the number that occurred in 2022.

  • This scaling allows trends to be compared when total counts/rates are dissimilar between crime types.

crime_type = 'FBI_type'
place_type = 'region'
select_places = None
select_crimes = None
for select_crime_type in pcp.select_crime_lists:
    display(Markdown(f"### {select_crime_type.replace('_',' ').title()}"))

    plot_data = pcp.melt_crime_df(
        crime_by_year_dfs,
        crime_type,
        place_type,
        select_crimes=select_crime_type
    )
    fig = pcp.plot_regional_crime(
            plot_data,
            crime_type,
            select_crimes=select_crime_type
    )

    fig.show(renderer=renderer)

Weapons And Homocide

Stealing

Assault And Battery

Society